package com.ccnu.demojava.nosql.redis;

import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class RJedis {
    private static final Logger log = LoggerFactory.getLogger(RJedis.class);

    private static int TEST_CAPITAL = 10 * 1024;

    /*
     * 功能描述
     * @author raohj
     * @date 2019/11/5
     * @descript
     * @params
     * @return
     */

    public static void testRedisBasic() {
        StopWatch stopWatch = new StopWatch();
        log.info("开始测试Jedis的基础功能");
        // 默认连接 连接db=0
        log.info("进行redis数据库的连接,采用默认的配置");
        Jedis jds = new Jedis();
        jds.connect();
        log.info("连接的数据库为:[" + jds.getDB() + "]");
        if (jds.dbSize() > 0) {
            log.info("当前数据库中已经存在的键值对数量为[" + jds.dbSize() + "]");
            jds.flushDB();    // 清除当前DB的数据
        } else {
            log.info("当前数据库无数据");
        }

        log.info("测试Redis存储字符串");
        stopWatch.start();
        {
            for (int i = 0; i < TEST_CAPITAL; i++) {
                String key = String.format("key%d", i);
                String value = String.format("value%d", i);
                jds.set(key, value);
            }

            jds.set("id1001", "421023412431");// 增加一个字符串
            jds.get("id1001");// 获取一个字符串
            jds.del("id1001");// 删除一个字符串
            log.info("打印容量为:" + jds.dbSize());
        }
        stopWatch.stop();
        log.info("压测" + TEST_CAPITAL + "条字符串，总耗时:" + stopWatch.getDuration().dividedBy(1000)  + "s");

        log.info("测试list");
        jds.flushDB();    // 清除当前DB的数据
        {
            for (int i = 0; i < 10; i++) {
                String value1 = String.format("Lvalue%d", i);
                jds.lpush("name", value1);
            }
            log.info("执行第一次lpush后容量为:" + jds.dbSize());

            for (int i = 0; i < 10; i++) {
                String value1 = String.format("Rvalue%d", i);
                jds.lpush("name1", value1);
            }
            log.info("执行第二次lpush后容量为:" + jds.dbSize());

            jds.lpop("name1");
            log.info("执行第一次lpop后容量为:" + jds.dbSize());

            for (String name : jds.lrange("name", 0, -1)) {
                log.info("list的值为:" + name);
            }
        }

        // 测试hashes
        log.info("测试hashes");
        jds.flushDB();    // 清除当前DB的数据
        {
            Map<String, String> paramsMap = new HashMap<>();
            paramsMap.put("name", "饶海军");
            paramsMap.put("age", "30");
            paramsMap.put("score", "100");
            jds.hmset("key-hashmap", paramsMap);

            if (jds.hexists("key-hashmap", "name")) {
                log.info("从hashes中获取姓名[" + jds.hget("key-hashmap", "name") + "]");
            }

            // 测试删除掉某个key
            if (jds.exists("key-hashmap")) {
                log.info("删除掉key[key-hashmap]");
                jds.del("key-hashmap");
            }
        }

        log.info("测试set");
        jds.flushDB();    // 清除当前DB的数据
        {
            jds.sadd("key-set1", "字符集合1");
            jds.sadd("key-set1", "字符集合1");
            // 输出所有的数据
            Set<String> keys = jds.keys("*");
            for (String keyStr : keys) {
                log.info("TYPE 获得key类型[" + jds.type(keyStr) + "]");
                log.info("key:" + keyStr + ", value:" + jds.spop("key-set1"));
            }
        }

        log.info("测试redis的超时时间");
        {
            log.info("测试expire开始");
            jds.set("key-expire", "测试值的超时时间");
            jds.expire("key-expire", 2L);    // 设置值2s后失效
            for (int i = 0; i < 100; i++) {
                try {
                    Thread.sleep(1000);    // 休息30s
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 测试值是否存在
                if (!jds.exists("key-expire")) {
                    log.info("测试expire成功");
                    break;
                } else {
                    log.debug("检测key超时时间[key-expire]");
                }
            }
        }

        {
            // 测试分布式加锁
            jds.setex("key-lock", 20L, "value-lock");
        }

        if (jds.isConnected()) {
            jds.close();
            log.debug("数据库关闭");
        }
    }

    public static void testRedisPool() {
        JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost");
        Jedis jedis = pool.getResource();
        String key = "key-rhj";
        String value = "value-rhj";
        jedis.set(key, value);
        jedis.close();
        pool.close();
    }
}
